/******************************************************************************* * Copyright (c) 2006, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.tests.commands; import java.util.HashMap; import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.Category; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.commands.contexts.Context; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.e4.core.commands.internal.HandlerServiceImpl; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.services.IServiceLocator; import org.eclipse.ui.tests.harness.util.UITestCase; import org.eclipse.ui.views.contentoutline.ContentOutline; /** * Tests various aspects of command state. * * @since 3.2 */ public class HandlerActivationTest extends UITestCase { static class ActTestHandler extends AbstractHandler { public String contextId; public int executionCount = 0; public ActTestHandler(String id) { super(); contextId = id; } @Override public Object execute(ExecutionEvent event) { executionCount++; return null; } } static class OutlineOnlyHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { IWorkbenchPart part = HandlerUtil.getActivePartChecked(event); if (!(part instanceof ContentOutline)) { throw new ExecutionException("bogus part " + part.getSite().getId()); } return null; } @Override public void setEnabled(Object evaluationContext) { IWorkbenchPart part = (IWorkbenchPart) HandlerUtil.getVariable( evaluationContext, ISources.ACTIVE_PART_NAME); setBaseEnabled(part instanceof ContentOutline); } } public static final String C_PREFIX = "org.eclipse.ui.tests.contexts."; public static final String C1_ID = C_PREFIX + ISources.ACTIVE_CONTEXT_NAME; public static final String C2_ID = C_PREFIX + ISources.ACTIVE_ACTION_SETS_NAME; public static final String C3_ID = C_PREFIX + ISources.ACTIVE_SHELL_NAME; public static final String C4_ID = C_PREFIX + ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME; private static final String CATEGORY_ID = "org.eclipse.ui.category.window"; public static final String CMD_ID = C_PREFIX + "command.testHandler"; private static final String[][] CREATE_CONTEXTS = { { C1_ID, "Active Contexts", null, IContextService.CONTEXT_ID_WINDOW }, { C2_ID, "Active Action Sets", null, IContextService.CONTEXT_ID_WINDOW }, { C3_ID, "Active Shell", null, IContextService.CONTEXT_ID_WINDOW }, { C4_ID, "Active Workbench Window Shell", null, IContextService.CONTEXT_ID_WINDOW }, { (C_PREFIX + ISources.ACTIVE_MENU_NAME), "Active Workbench Window Shell", null, IContextService.CONTEXT_ID_WINDOW }, }; public static final String H1 = C_PREFIX + "h1"; public static final String H2 = C_PREFIX + "h2"; public static final String H3 = C_PREFIX + "h3"; private ICommandService commandService; private IContextService contextService; private IHandlerService handlerService; private IServiceLocator services; private Map testContextActivations = new HashMap(); private Map testHandlerActivations = new HashMap(); private Map testHandlers = new HashMap(); /** * Constructor for <code>HandlerActivationTest</code>. * * @param name * The name of the test */ public HandlerActivationTest(String name) { super(name); services = PlatformUI.getWorkbench(); contextService = services .getService(IContextService.class); commandService = services .getService(ICommandService.class); handlerService = services .getService(IHandlerService.class); } private IContextActivation activateContext(String contextId) { IContextActivation c = contextService.activateContext(contextId); testContextActivations.put(contextId, c); return c; } /** * @param cmd * @param handlerId * @throws ExecutionException * @throws NotDefinedException * @throws NotEnabledException * @throws NotHandledException */ private void assertHandlerIsExecuted(Command cmd, String handlerId) throws ExecutionException, NotDefinedException, NotEnabledException, NotHandledException { ActTestHandler handler = (ActTestHandler) testHandlers.get(handlerId); int count = handler.executionCount; cmd.executeWithChecks(handlerService.createExecutionEvent(cmd, null)); assertEquals("The handler count should be incremented", count + 1, handler.executionCount); } /** * @param contextId * @param handlerId * @param expressionInfo */ private void createHandlerActivation(String contextId, String handlerId, String[] expressionInfo) { ActiveContextExpression expression; expression = new ActiveContextExpression(contextId, expressionInfo); makeHandler(handlerId, contextId, expression); } @Override protected void doSetUp() throws Exception { for (final String[] contextInfo : CREATE_CONTEXTS) { final Context context = contextService.getContext(contextInfo[0]); if (!context.isDefined()) { context.define(contextInfo[1], contextInfo[2], contextInfo[3]); } } Command cmd = commandService.getCommand(CMD_ID); if (!cmd.isDefined()) { Category cat = commandService.getCategory(CATEGORY_ID); cmd.define("Test Handler", "Test handler activation", cat); cmd.setHandler(HandlerServiceImpl.getHandler(CMD_ID)); } } @Override protected void doTearDown() throws Exception { handlerService.deactivateHandlers(testHandlerActivations.values()); testHandlerActivations.clear(); contextService.deactivateContexts(testContextActivations.values()); testContextActivations.clear(); super.doTearDown(); } /** * @throws ExecutionException * @throws NotDefinedException * @throws NotEnabledException * @throws NotHandledException */ private void doTestForBreak() throws ExecutionException, NotDefinedException, NotEnabledException, NotHandledException { Command cmd = commandService.getCommand(CMD_ID); assertTrue("Command should be defined", cmd.isDefined()); assertFalse("Should not be handled yet", cmd.isHandled()); IContextActivation c1 = activateContext(C1_ID); IContextActivation c2 = activateContext(C2_ID); IContextActivation c3 = activateContext(C3_ID); assertTrue("Should still be handled", cmd.isHandled()); assertHandlerIsExecuted(cmd, H3); contextService.deactivateContext(c3); contextService.deactivateContext(c2); contextService.deactivateContext(c1); } /** * @param currentHandler * @param expression1 */ private void makeHandler(String handler, String context, ActiveContextExpression expression) { IHandler currentHandler = null; if (!testHandlers.containsKey(handler)) { currentHandler = new ActTestHandler(context); testHandlers.put(handler, currentHandler); } else { currentHandler = (IHandler) testHandlers.get(handler); } testHandlerActivations.put(handler, handlerService.activateHandler( CMD_ID, currentHandler, expression)); } public void testExceptionThrowingHandler(){ try { handlerService.executeCommand("org.eclipse.ui.tests.command.handlerException", null); fail("An exception should be thrown for this handler"); } catch (Exception e) { if(!(e instanceof ExecutionException)) { fail("Unexpected exception while executing command", e); } } } public void testBasicHandler() throws Exception { createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); Command cmd = commandService.getCommand(CMD_ID); assertTrue("Command should be defined", cmd.isDefined()); assertFalse("Should not be handled yet", cmd.isHandled()); IContextActivation activationC1 = activateContext(C1_ID); assertTrue("Should definitely be handled", cmd.isHandled()); ActTestHandler handler1 = (ActTestHandler) testHandlers.get(H1); int count = handler1.executionCount; cmd.executeWithChecks(handlerService.createExecutionEvent(cmd, null)); assertEquals("The handler count should be correct", count + 1, handler1.executionCount); contextService.deactivateContext(activationC1); assertFalse("Should not be handled", cmd.isHandled()); } public void testForBreak123() throws Exception { createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); doTestForBreak(); } public void testForBreak132() throws Exception { createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); doTestForBreak(); } public void testForBreak213() throws Exception { createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); doTestForBreak(); } public void testForBreak231() throws Exception { createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); doTestForBreak(); } public void testForBreak312() throws Exception { createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); doTestForBreak(); } public void testForBreak321() throws Exception { createHandlerActivation(C3_ID, H3, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_SHELL_NAME }); createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); doTestForBreak(); } public void testForNegativeNumber() throws Exception { String c5_id = C_PREFIX + ISources.ACTIVE_MENU_NAME; String h5 = C_PREFIX + "h5"; createHandlerActivation(c5_id, h5, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_MENU_NAME }); createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); Command cmd = commandService.getCommand(CMD_ID); activateContext(C1_ID); activateContext(c5_id); assertHandlerIsExecuted(cmd, h5); } public void testTwoHandlers() throws Exception { createHandlerActivation(C1_ID, H1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); createHandlerActivation(C2_ID, H2, new String[] { ISources.ACTIVE_CONTEXT_NAME, ISources.ACTIVE_ACTION_SETS_NAME }); Command cmd = commandService.getCommand(CMD_ID); assertTrue("Command should be defined", cmd.isDefined()); assertFalse("Should not be handled yet", cmd.isHandled()); IContextActivation activationC1 = activateContext(C1_ID); assertTrue("Should definitely be handled", cmd.isHandled()); ActTestHandler handler1 = (ActTestHandler) testHandlers.get(H1); int count1 = handler1.executionCount; cmd.executeWithChecks(new ExecutionEvent()); assertEquals("The handler count should be incremented", count1 + 1, handler1.executionCount); activateContext(C2_ID); assertTrue("Should still be handled", cmd.isHandled()); ActTestHandler handler2 = (ActTestHandler) testHandlers.get(H2); int count2 = handler2.executionCount; count1 = handler1.executionCount; cmd.executeWithChecks(new ExecutionEvent()); assertEquals("The handler1 count should not be incremented", count1, handler1.executionCount); assertEquals("The handler2 count should be incremented", count2 + 1, handler2.executionCount); contextService.deactivateContext(activationC1); assertTrue("Will still be handled", cmd.isHandled()); } public void testLocalContext() throws Exception { IWorkbenchWindow window = openTestWindow("org.eclipse.ui.resourcePerspective"); OutlineOnlyHandler handler = new OutlineOnlyHandler(); IEvaluationContext oldContext = handlerService .createContextSnapshot(false); testHandlerActivations.put(handler, handlerService.activateHandler( CMD_ID, handler)); Command cmd = commandService.getCommand(CMD_ID); ParameterizedCommand pcmd = new ParameterizedCommand(cmd, null); try { handlerService.executeCommand(pcmd, null); fail("this should not be executable"); } catch (NotEnabledException e) { // good } assertFalse(cmd.isEnabled()); window.getActivePage().showView(IPageLayout.ID_OUTLINE); IEvaluationContext outlineContext = handlerService.createContextSnapshot(false); handlerService.executeCommand(pcmd, null); assertTrue(cmd.isEnabled()); try { handlerService.executeCommandInContext(pcmd, null, oldContext); fail("this should not be executable"); } catch (NotEnabledException e) { // good } assertTrue(cmd.isEnabled()); handlerService.executeCommandInContext(pcmd, null, outlineContext); } }